<?php
namespace Todo\Model;
use Think\Model;

/**
 * 自定义基础类，支持一级缓存（keyFind方法）
 * User: yepanpan
 * Date: 2016/8/8
 * Time: 17:59
 */
class BaseModel extends Model
{
    private $cached=array();

    /**
     * 插入一条数据
     * @param array $data=null 数据，为null则从POST取
     * @return int|bool
     */
    public function insert($data = null){
        if(!$data) $data = $_POST;
        if(!$this->create($data)) return false;
        $this->startTrans();
        $id = $this->add();
        if($id === false){
            $this->rollback();
            return false;
        }else{
            $this->commit();
            return $id;
        }
    }

    /**
     * 更新一条数据
     * @param int $id 主键的值
     * @param array $data=null 数据，为null则从POST取
     * @return bool
     */
    public function update($id,$data=null){
        if(!$data) $data = $_POST;
        $data[$this->getPk()] = $id;
        if(!$this->create($data)) return false;
        $this->startTrans();
        if(false === $this->save()){
            $this->rollback();
            return false;
        }else{
            $this->commit();
            return true;
        }
    }

    /**
     * 分页查询
     * @param array $where 条件
     * @param int $page=0 当前页码
     * @param int $limit=20 返回条数
     * @param string $order=id DESC 排序
     * @return mixed 查询结果
     */
    public function pageSelect($where, $page=0, $limit=20, $order='id DESC'){
        return $this->where($where)->page($page, $limit)->order($order)->select();
    }

    /**
     * 查询总数
     * @param $where
     * @return mixed
     */
    public function pageCount($where){
        return $this->where($where)->count();
    }

    /**
     * 查询一条数据
     * @param array $where 查询条件
     * @param bool $field=true 返回的字段名称，默认全部返回
     * @return bool|mixed
     */
    public function findOne($where, $field=true){
        $info = $this->where($where)->find();
        if(!$info) return false;
        $this->cached[$info['id']] = $info;
        return $field === true ? $info : $info[$field];
    }

    /**
     * 通过主键取数据
     * @param int $id
     * @param bool $field=true
     * @return mixed|array
     */
    public function keyFind($id, $field=true){
        if(isset($this->cached[$id])){
            $row = $this->cached[$id];
        }else{
            $row = $this->findOne(array($this->pk => $id));
            $this->cached[$id] = $row;
        }
        if(!$row) return false;

        return $field === true ? $row : $row[$field];
    }

    /**
     * 根据字段名和值，查询第一条匹配的数据
     * @param string $field 字段名
     * @param mixed $val 字段的值
     * @return mixed|null
     */
    public function findByField($field,$val){
       return $this->findOne(array($field, $val));
    }

    /**
     * 启用
     * @param int $id 主键
     * @return bool
     */
    public function enable($id){
        return $this->where(array($this->getPk() => $id))->save(array('status'=>1));
    }

    /**
     * 禁用
     * @param int $id 主键
     * @return bool
     */
    public function disable($id){
        return $this->where(array($this->getPk() => $id))->save(array('status'=>2));
    }

    /**
     * 删除(如果有字段is_del且$true=false,假删除)
     * @param int $id 主键
     * @param boolean $true=false 是否假删除
     * @return bool
     */
    public function del($id, $true=false){
        $this->where(array($this->getPk() => $id));
        if($true) return $this->delete();

        $fields = $this->getDbFields();
        if(in_array('is_del', $fields)) return $this->save(array('is_del'=>1));

        return $this->delete();
    }


    /**
     * 执行SQL
     * @param string $sql SQL语句
     * @param array $replace=null 替换
     * @return bool
     */
    public function exeSql($sql, $replace = null){
        if($replace){
            foreach ($replace as $k => $v){
                $sql = str_replace('{{'. $k. '}}', $v, $sql);
            }
        }
        return $this->execute($sql) !== false;
    }

    //-------------------------------------清除缓存------------------------------
    protected function _after_insert($data,$options) {
        unset($this->cached);
    }
    protected function _after_update($data,$options) {
        unset($this->cached);
    }
    protected function _after_delete($data,$options) {
        unset($this->cached);
    }
    //-------------------------------------即时重建缓存-------------------------------
}